package sg.edu.nus.iss.cats.controller;

import sg.edu.nus.iss.cats.dataaccess.*;
import sg.edu.nus.iss.cats.model.*;
import sg.edu.nus.iss.cats.exception.*;

import java.util.Date;

/**
  * A Business Delegate that abstracts out the business specific calls
  * and exceptions . The web tier does not need to know about the
  * business-specific details
  **/
public class CourseManager {

    private CourseDAO courseDAO;

    public CourseManager() {
        courseDAO = DAOFactory.getInstance().getCourseDAO();
    }

    public Course[] findCoursesByEmployee(String empId)
                    throws CourseNotFoundException {

        Course[] courses;
        try {
            courses = courseDAO.findCoursesByEmployee(empId);
        } catch (Exception e) {
            throw new CourseNotFoundException();
        }
        return courses;
    }

    public Course findCourse(String courseId) throws CourseNotFoundException {
        Course course;
        try {
            course = courseDAO.findCourse(courseId);
        } catch (DAOException e) {
            throw new CourseNotFoundException(
                "Error retrieving the course: " + e.toString());
        }
        return course;
    }

    public int getNewCourseId () throws CourseCreateException {
        SequenceManager mgr = DAOFactory.getInstance().getSequenceManager();
        int value = -1;
        try {
            value = mgr.getNextValue("CourseApplications");
        } catch (DAOException e) {
            throw new CourseCreateException(
                "Could not assign an id. " + "Nested Exception is: " + e);
        }
        return value;
    }
    
   
    public void updateCourse (Course course, String modifierId, String comment)
                              throws CourseNotFoundException {
        updateCourse (course, Course.UPDATED, modifierId, comment);
    }

    private void updateCourse (Course course, String newStatus,
                               String modifierId, String comment)
                               throws CourseNotFoundException {
        try {
            course.setStatus(newStatus);
            courseDAO.updateCourse(course);
            insertCourseEvent(course, modifierId, comment);
        } catch (DAOUpdateException e) {
            throw new CourseNotFoundException();
        } catch (DAOException e) {
            throw new CourseNotFoundException();
        }
    }

    public void withdrawCourse(String courseId, String modifierId, String comment)
                               throws CourseNotFoundException {
        modifyCourseStatus(courseId, Course.WITHDRAWN, modifierId, comment);
    }

    public void approveCourse(String courseId, String modifierId, String comment)
                               throws CourseNotFoundException {
        modifyCourseStatus(courseId, Course.APPROVED, modifierId, comment);
    }

    public void rejectCourse(String courseId, String modifierId, String comment)
                               throws CourseNotFoundException {
        modifyCourseStatus(courseId, Course.REJECTED, modifierId, comment);
    }

    private void modifyCourseStatus(String courseId, String newStatus,
                                   String modifierId, String comment)
                                   throws CourseNotFoundException {
         // First checks it exists!
        Course course = findCourse(courseId);
        if (course == null) {
            throw new CourseNotFoundException();
        }
        updateCourse (course, newStatus, modifierId, comment);
    }


    public void insertCourse(Course course, String modifierId, String comment)
                 throws CourseCreateException {
        try {
            course.setStatus(Course.SUBMITTED);
            courseDAO.insertCourse(course);
            insertCourseEvent(course, modifierId, comment);
        } catch (DAOUpdateException e) {
            throw new CourseCreateException();
        } catch (DAOException e) {
            throw new CourseCreateException();
        }
    }

    private void insertCourseEvent(Course course, String modifierId,
                                   String comment) throws DAOException {
        CourseEvent action = new CourseEvent();
        int i = getNewCourseEventId();
        System.out.println("CMgr: new coursevent number: " +  i);
        action.setCourseEventId(i);
        action.setCourseId(course.getCourseId());
        action.setTimeStamp(new Date());
        action.setEventType(course.getStatus());
        action.setEventBy(modifierId);
        action.setComment(comment);
        courseDAO.insertCourseEvent(action);
        
    }
    
    private int getNewCourseEventId () throws DAOException {
        SequenceManager mgr = DAOFactory.getInstance().getSequenceManager();
        int value = -1;
        value = mgr.getNextValue("CourseEvents");        
        return value;
    }


}